package org.hawk.gwt.ppc.scanner.utils;

import org.hawk.gwt.ppc.utils.Name;

/**
 * Represents java variable declaration.
 * Holds all necessary data to get information about variable.
 * @author alex.bereznevatiy@gmail.com
 */
public class JavaVariable {
	private String name;
	private String type;
	private int index;
	private JavaScope scope;
	private boolean varArg;

	JavaVariable(String name,String type, int index,JavaScope scope) {
		this(name,type,index,scope,false);
	}
	public JavaVariable(String name, String type, int index,
			JavaScope scope, boolean varArg) {
		this.name = name;
		this.type = type;
		this.index = index;
		this.scope = scope;
		this.varArg = varArg;
	}
	/**
	 * @param index
	 * @return <code>true</code> if this variable is accessible 
	 * at runtime at the specified index of iterator (token).
	 */
	public boolean isDeclaredAt(int index) {
		return this.index<=index;
	}
	/**
	 * @return <code>true</code> if this variable represents
	 * method variable length argument.
	 */
	public boolean isVarArg() {
		return varArg;
	}
	@Override
	public boolean equals(Object obj) {
		if(obj==this)return true;
		if(obj instanceof JavaVariable){
			JavaVariable var = (JavaVariable)obj;
			return var.getName().equals(getName())
				&&var.getType().equals(getType());
		}
		return false;
	}
	/**
	 * @return name this variable declared with
	 */
	public String getName() {
		return name;
	}
	/**
	 * @return type name of this variable including type parameters.
	 */
	public String getType() {
		if(scope==null||Name.isSimpleName(type)){
			return type;
		}
		return scope.resolveType(type);
	}

	String getRawType() {
		return type;
	}
	/**
	 * @return index of token where this variable is declared
	 */
	public int getIndex() {
		return index;
	}
	/**
	 * @return scope of this variable visibility
	 */
	public JavaScope getScope() {
		return scope;
	}

	void setScope(JavaScope scope) {
		this.scope = scope;
	}

	@Override
	public String toString() {
		return getType()+' '+getName();
	}
}
